﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web;
using System.Data;

namespace SPDEV.Search.Utilities
{
    /// <summary>
    /// Generate a list of all known metadata about an item, specified by url.
    /// </summary>
    public class DisplayAllKnownPropertiesForContentAdminLayoutsPage : LayoutsPageBase
    {
        // UI Controls
        protected SPGridView gridView;

        private string ItemUrl { get; set; }

        #region Ctrs

        /// <summary>
        /// Default
        /// </summary>
        public DisplayAllKnownPropertiesForContentAdminLayoutsPage()
            : base()
        {
        }

        /// <summary>
        /// Useful for testing
        /// </summary>
        /// <param name="itemUrl"></param>
        public DisplayAllKnownPropertiesForContentAdminLayoutsPage(string itemUrl)
        {
            this.ItemUrl = itemUrl;
        }

        #endregion

        /// <summary>
        /// Generate bound datatable of item properties, based on URL
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // get content item (by url?)
            string itemUrl = HttpContext.Current.Request.QueryString["Url"];
            if (!string.IsNullOrEmpty(itemUrl))
            {
                if (Uri.IsWellFormedUriString(itemUrl, UriKind.RelativeOrAbsolute))
                {
                    this.ItemUrl = itemUrl;
                    var properties = FindItemPropertiesOrNull();
                    if (properties != null)
                    {
                        DataTable datatable = GenerateDataTableOfItemProperties(properties);
                        gridView.DataSource = datatable;
                        gridView.DataBind();
                    }
                }
            }
        }

        /// <summary>
        /// Create a datatable, using the properties of the spfile / splistitem
        /// </summary>
        /// <param name="properties"></param>
        /// <returns></returns>
        private static DataTable GenerateDataTableOfItemProperties(Dictionary<string, string> properties)
        {
            DataTable datatable = new DataTable();
            datatable.AddColumns(new string[] { "Field", "Value" });

            foreach (var keyValue in properties)
            {
                DataRow row = datatable.NewRow();
                row["Field"] = keyValue.Key;
                row["Value"] = keyValue.Value;
                datatable.Rows.Add(row);
            }

            return datatable;
        }

        /// <summary>
        /// Generate a dictionary of properties; obtain spfile / splistitem properties, if they exist
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, string> FindItemPropertiesOrNull()
        {
            using (SPSite site = new SPSite(this.ItemUrl))
            {
                string siteCollectionComponent = site.Url;
                string webComponent = this.ItemUrl.Replace(siteCollectionComponent, string.Empty);
                string fileComponent = webComponent;

                using (SPWeb web = site.OpenWeb(webComponent.Split("?".ToCharArray())[0], false))
                {
                    try
                    {
                        var itemProperties = GeneratePropertiesFromItemInWeb(fileComponent, web);
                        return itemProperties;
                    }
                    catch
                    {
                        return null;
                    }
                }
            }
        }

        /// <summary>
        /// Generate all properties from the file existing in web
        /// </summary>
        /// <param name="fileComponent"></param>
        /// <param name="web"></param>
        /// <returns></returns>
        private static Dictionary<string, string> GeneratePropertiesFromItemInWeb(string fileComponent, SPWeb web)
        {
            var itemAtPath = web.GetObject(fileComponent);
            var file = GetFileOrNull(itemAtPath);

            var itemProperties = new Dictionary<string, string>();
            
            if (null != file)
                AddFileProperties(itemProperties, file);

            if (Uri.IsWellFormedUriString(fileComponent, UriKind.Relative))
            {
                // todo : handle listitem (with ID)
            }

            return itemProperties;
        }

        #region Helpers

        private static SPFile GetFileOrNull(object itemObject)
        {
            if (itemObject is SPFile)
                return itemObject as SPFile;
            else
            {
                if (itemObject is SPListItem)
                {
                    var listItem = itemObject as SPListItem;
                    if (listItem.File != null)
                    {
                        if (listItem.File.Exists)
                            return listItem.File;
                    }
                }
            }
            return null;
        }

        private static SPListItem GetItemOrNull(object itemObject)
        {
            if (itemObject is SPListItem)
                return itemObject as SPListItem;
            else
            {
                if (itemObject is SPFile)
                {
                    var file = itemObject as SPFile;
                    if (file.Item != null)
                    {
                        return file.Item;
                    }
                }
            }
            return null;
        }

        #endregion

        #region Property Generators

        private static void AddItemProperties(Dictionary<string, string> itemProperties, SPListItem itemAtPath)
        {
            if (itemAtPath is SPListItem)
            {
                var fieldNames = (itemAtPath as SPListItem).Fields.Cast<SPField>();
                foreach (SPField field in fieldNames)
                {
                    try
                    {
                        itemProperties.Add(field.Title, string.Format("{0}", (itemAtPath as SPListItem)[field.Id]));
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }

        private static void AddFileProperties(Dictionary<string, string> itemProperties, SPFile itemAtPath)
        {
            var properties = itemAtPath.Properties;
            foreach (string key in properties.Keys)
            {
                try
                {
                    itemProperties.Add(key, string.Format("{0}", properties[key]));
                }
                catch (Exception ex)
                {
                }
            }
        }

        #endregion
    }
}
